#include "StdAfx.h"
#include "MemoEdit.h"

static const wchar_t unicodeTag = 0xFEFF;

static DWORD CALLBACK LoadCallback( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb ) 
{ 
    HANDLE hFile = (HANDLE)dwCookie; 
    ::ReadFile(hFile, pbBuff, cb, (DWORD*)pcb, NULL); 
    return 0; 
}

static DWORD CALLBACK SaveCallback( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb ) 
{ 
    HANDLE hFile = (HANDLE) dwCookie; 
    ::WriteFile(hFile, pbBuff, cb, (DWORD*)pcb, NULL); 
    return 0;
}

void MemoEdit::Save(const std::wstring fileName, bool unicode)
{
    DWORD dwCurrentFilePosition = -1;

    if (hReadFile != INVALID_HANDLE_VALUE)
    {
        dwCurrentFilePosition = SetFilePointer( hReadFile,  0, NULL, FILE_CURRENT);
        ::CloseHandle(hReadFile);
    }

    HANDLE hWriteFile = ::CreateFile(fileName.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    if (unicode)
    {
        DWORD nWritten;
        ::WriteFile(hWriteFile, (LPVOID)&unicodeTag, sizeof(wchar_t), &nWritten, NULL);
    }

    EDITSTREAM   eds;
    eds.dwCookie = (DWORD) hWriteFile; 
    eds.dwError = 0; 
    eds.pfnCallback = SaveCallback;

    StreamOut( unicode ? SF_UTEXT : SF_TEXT, eds );

    ::CloseHandle(hWriteFile);

    if (dwCurrentFilePosition >= 0) // file was opened before writing
    {
        hReadFile = ::CreateFile(fileName.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
        ::SetFilePointer(hReadFile, dwCurrentFilePosition, NULL, FILE_BEGIN);
    }
}

void MemoEdit::Load(const std::wstring fileName, bool unicode)
{
    if (hReadFile != INVALID_HANDLE_VALUE)
        ::CloseHandle(hReadFile);

    hReadFile = ::CreateFile(fileName.c_str(), GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0);
    if (unicode)
        ::SetFilePointer(hReadFile, sizeof(wchar_t), NULL, FILE_BEGIN);

    EDITSTREAM   eds;
    eds.dwCookie = (DWORD) hReadFile; 
    eds.dwError = 0; 
    eds.pfnCallback = LoadCallback;

    StreamIn(unicode ? SF_UTEXT : SF_TEXT, eds);
}



